package com.module.lemlin.rxhttp

import com.blankj.utilcode.util.AppUtils
import com.blankj.utilcode.util.LogUtils
import okhttp3.*
import okhttp3.MediaType.Companion.toMediaTypeOrNull
import okio.Buffer
import java.util.*
import java.util.concurrent.TimeUnit

object HttpServiceFactory {
    private fun client(isInterceptor: Boolean = true): OkHttpClient.Builder {
        val builder = OkHttpClient.Builder()
        builder.writeTimeout(30.toLong(), TimeUnit.SECONDS)
        builder.readTimeout(30.toLong(), TimeUnit.SECONDS)
        builder.connectTimeout(30.toLong(), TimeUnit.SECONDS)
//        if (isInterceptor)
//            builder.addInterceptor(SigningInterceptor())
        if (AppUtils.isAppDebug())
            builder.addInterceptor(LoggingInterceptor())
        return builder
    }

    fun create(listener: WebSocketListener, wsUrl: String): WebSocket {
        val request: Request = Request.Builder()
            .url(wsUrl)
            .build()
        return client(isInterceptor = false).build().newWebSocket(request, listener)
    }

    /**
     * Log拦截
     */
    internal class LoggingInterceptor : Interceptor {

        private val mediaType: MediaType = "application/octet-stream".toMediaTypeOrNull()!!

        override fun intercept(chain: Interceptor.Chain): Response {
            //发送时截取数据
            val request = chain.request()
            val t1 = System.nanoTime()
            val body = request.body
            val buffer = Buffer()
            if (body?.contentType() != mediaType){
                body?.writeTo(buffer)
            }

            val send = String.format(
                Locale.CHINA, ("发送请求:%s%n请求JSON:%s"),
                request.url,
                if (body?.contentType() == mediaType)
                    "This is the file upload" else buffer.readUtf8()
            )
            LogUtils.e(send)

            //接收时截取数据
            val response = chain.proceed(request)
            val t2 = System.nanoTime()
            val responseBody = response.peekBody((1024 * 1024).toLong())

            val accept = String.format(
                Locale.CHINA, ("接收响应:%s%n请求时间:%.1fms%n报文信息:%s返回JSON:%s"),
                response.request.url,
                (t2 - t1) / 1e6,
                response.headers,
                if (responseBody.contentType() == mediaType)
                    "This is the file download" else responseBody.string()
            )
            LogUtils.e(accept)

            return response
        }
    }
}